#include "parsing.h"

unsigned char IsNumber( char c )
{
	return (c>='0'&& c<='9');
}

unsigned char Char2Hex( char c )
{
	return IsNumber(c)? c-='0' : (c>='a'&& c<='f')? c-='a'-10 : (c>='A'&& c<='F')? c-='A'-10:0xff;
}


unsigned char ParseInt( char *s, unsigned int *out)
{
    *out = 0;

	char c = 0;

	for(;;)
	{
		if (IsNumber(*s))
		{
			*out = ( *out * 10 ) + (*s-'0');
		}
		else
		{
			return c;		
		}
		s++;
		c++;
	}
}

unsigned char ParseInt8( char *s, unsigned char *out)
{
	unsigned int iout;
	char r = ParseInt( s, &iout);
	if ( r<256 )
	{
		*out = iout;
		return r;
	}
	return 0;
}

unsigned char ParseHex8( char *s, unsigned char *out)
{
	if (*s!=0)
	{
		char h,l;

		h  = Char2Hex( *s );
		if ( h<=0xf )
		{
			l  = Char2Hex( *(s+1) );
			if ( l<=0xf )
			{
				*out = ( h<<4 ) + l;
				return 2;
			}
		}
		
	}

	return 0;
}

unsigned char ParseHex16( char *s, unsigned int *out)
{
	unsigned char h,l;

	if ( ParseHex8( s, &h) )
	{
		s+=2;
		if ( ParseHex8( s, &l) )
		{
			unsigned int val = h;

			*out = (val<<8) | l;
			return 4;
		}
	}

	return 0;
}

unsigned char Parse( char *p, char *str, char *data )
{
	char total = 0;
	
	while( *p != 0 )
	{
		char inc = 1;
		char val = 1;
		
		if (*p == '%')
		{
			p++;

			if (*p=='i')
			{
				p++;
				val = ParseInt8( str, (unsigned char *)data );
			}
			else if (*p=='x')
			{
				p++;
				val = ParseHex8( str, (unsigned char *)data );
			}
			else if (*p=='I')
			{
				p++;
				val = ParseInt( str, (unsigned int *)data );
				inc = 2;
			}
			else if (*p=='X')
			{
				p++;
				val = ParseHex16( str, (unsigned int *)data );
				inc = 2;
			}

			if ( val > 0)
			{
				str += val;
				data += inc;
			}
			else
			{
				return 0;
			}
		}
		else if ( *p != *str )
		{
			return 0;
		}
		else
		{
			p++;
			str++;
			val = 1;
		}

		total+=val;
	}

	return total;
}
